﻿//-----------------------------------------------------------------------
// <copyright file="PathSuggestionProvider.cs" author="Artak Mkrtchyan">
//     Creative Commons - GNU General Public License (http://creativecommons.org/licenses/GPL/2.0/
// </copyright>
// <author>Artak Mkrtchyan</author>
// <email>mkArtak@gmail.com</email>
// <date>08/02/2013</date>

using ConsoleHoster.Common.Utilities.IO;
using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleHoster.Model.Suggestions
{
	internal sealed class PathSuggestionProvider : IPathSuggestionProvider
	{
		private readonly IFileSystemContentProvider directoryContentProvider;
		private string suggestionBase;
		private int? lastSuggestionIndex = null;
		private readonly IList<string> suggestions = new List<string>();

		public PathSuggestionProvider()
			: this(new FileSystemContentProvider())
		{

		}

		internal PathSuggestionProvider(IFileSystemContentProvider argDirectoryContentProvider)
		{
			if (argDirectoryContentProvider == null)
			{
				throw new ArgumentNullException("argDirectoryContentProvider");
			}
			this.directoryContentProvider = argDirectoryContentProvider;
		}

		public string[] PrepareSuggestions(string argSourceFolder, string argSuggestionBase, bool argFoldersOnly)
		{
			if (!this.directoryContentProvider.DirectoryExists(argSourceFolder))
			{
				throw new ArgumentException("No such directory");
			}

			this.SuggestionBase = argSuggestionBase;
			this.LastSuggestionIndex = null;

			this.Suggestions.Clear();

			string[] tmpItems = argFoldersOnly ?
				this.directoryContentProvider.GetFolders(argSourceFolder, argSuggestionBase) :
				this.directoryContentProvider.GetAllItems(argSourceFolder, argSuggestionBase);

			foreach (string tmpItem in tmpItems)
			{
				this.Suggestions.Add(SelectNameOnly(tmpItem));
			}

			return this.Suggestions.ToArray();
		}

		public string GetNextSuggestion()
		{
			if (this.LastSuggestionIndex.HasValue)
			{
				this.LastSuggestionIndex++;
			}
			else
			{
				this.LastSuggestionIndex = 0;
			}

			return this.Suggestions.Any() ? this.Suggestions[this.LastSuggestionIndex.Value] : null;
		}

		public string GetPreviousSuggestion()
		{
			if (this.LastSuggestionIndex.HasValue)
			{
				this.LastSuggestionIndex--;
			}
			else
			{
				this.LastSuggestionIndex = this.Suggestions.Count - 1;
			}
			return this.Suggestions.Any() ? this.Suggestions[this.LastSuggestionIndex.Value] : null;
		}

		private static string SelectNameOnly(string argPath)
		{
			int tmpIndex = argPath.LastIndexOf('/');
			if (tmpIndex == -1)
			{
				tmpIndex = argPath.LastIndexOf('\\');
			}

			return argPath.Substring(tmpIndex + 1);
		}

		#region Properties
		private IList<string> Suggestions
		{
			get
			{
				return this.suggestions;
			}
		}

		public int? LastSuggestionIndex
		{
			get
			{
				return this.lastSuggestionIndex;
			}
			private set
			{
				this.lastSuggestionIndex = value;
				if (this.lastSuggestionIndex.HasValue)
				{
					if (value < 0)
					{
						this.lastSuggestionIndex = this.Suggestions.Count - 1;
					}
					else if (value >= this.Suggestions.Count)
					{
						this.lastSuggestionIndex = 0;
					}
				}
			}
		}

		public string SuggestionBase
		{
			get
			{
				return this.suggestionBase;
			}
			private set
			{
				this.suggestionBase = value;
			}
		}
		#endregion
	}
}
